"use strict";
// 8、从一个简单的例子引入
// 模特类
class Model {
    constructor(sex, custom) {
        this.sex = sex;
        this.custom = custom;
    }
    takePicture() {
        console.log(`性别：${this.sex},服装：${this.custom}`);
    }
}
// 各找50个模特来拍照
for (let i = 0; i < 50; i++) {
    let maleModel = new Model("男", i);
    maleModel.takePicture();
}
for (let i = 0; i < 50; i++) {
    let femaleModel = new Model("女", i);
    femaleModel.takePicture();
}
// 改良的模特类
class NewModel {
    constructor(sex) {
        this.sex = sex;
    }
    takePicture(custom) {
        console.log(`性别：${this.sex},服装：${custom}`);
    }
}
// 各找50个模特来拍照
for (let i = 0; i < 50; i++) {
    let maleModel = new NewModel("男");
    maleModel.takePicture(i);
}
for (let i = 0; i < 50; i++) {
    let femaleModel = new NewModel("女");
    femaleModel.takePicture(i);
}
// 文件上传的例子--->1
class Upload {
    constructor(uploadType, filename, fileSize) {
        this.uploadType = uploadType;
        this.filename = filename;
        this.fileSize = fileSize;
        this.id = null;
    }
    init(id) {
        this.id = id;
        console.log("上传已经初始化完成了。");
    }
}
// 下载初始化函数
let fileId = 0;
function startUpload(uploadType, files) {
    for (let i = 0; i < files.length; i++) {
        const uploadObj = new Upload(uploadType, files[i].filename, files[i].fileSize);
        uploadObj.init(fileId); // 已经初始化完成
        fileId++; // 文件id唯一
    }
}
startUpload("plugin", [
    {
        fileName: "1.txt",
        fileSize: 1000,
    },
    {
        fileName: "2.html",
        fileSize: 3000,
    },
    {
        fileName: "3.txt",
        fileSize: 5000,
    },
]);
startUpload("flash", [
    {
        fileName: "4.txt",
        fileSize: 1000,
    },
    {
        fileName: "5.html",
        fileSize: 3000,
    },
    {
        fileName: "6.txt",
        fileSize: 5000,
    },
]);
// 文件上传的例子--->2
// 改良后的upload类
class NewUpload {
    constructor(uploadType) {
        this.uploadType = uploadType;
    }
}
// 创建upload享元对象的工厂方法
const uploadFactory = (function () {
    let flyWeightedMap = {}; // 享元对象的哈希表
    return function (uploadType) {
        if (flyWeightedMap[uploadType]) {
            return flyWeightedMap[uploadType];
        }
        flyWeightedMap[uploadType] = new NewUpload(uploadType);
        return flyWeightedMap[uploadType];
    };
})();
// upload对象的外部状态管理方法
const uploadStateManager = (function () {
    let uploadDataBase = {};
    return {
        add(id, uploadType, fileName, fileSize) {
            // 创建享元对象及初始化方法
            let flyWeightedObj = uploadFactory(uploadType); // 创建一个享元对象
            console.log("上传已经初始化完成了。");
            uploadDataBase[id] = {
                // uploadDataBase对象负责记录外部状态
                fileName,
                fileSize,
            };
            return flyWeightedObj; // 返回享元对象
        },
        /**
         * @param id 唯一标识的id号
         * @param flyWeightedObj 享元对象本身
         */
        // 会根据情况实时的动态改写享元对象
        setExternalState(id, flyWeightedObj) {
            // 设置外部状态方法
            let state = uploadDataBase[id];
            for (let key in state) {
                flyWeightedObj[key] = state[key];
            }
        },
    };
})();
// 重写startUpload方法
let _id = 0;
function startUpload2(uploadType, files) {
    for (let i = 0; i < files.length; i++) {
        uploadStateManager.add(_id, uploadType, files.fileName, files.fileSize);
    }
}
// 测试用例
startUpload2("plugin", [
    {
        fileName: "1.txt",
        fileSize: 1000,
    },
    {
        fileName: "2.html",
        fileSize: 3000,
    },
    {
        fileName: "3.txt",
        fileSize: 5000,
    },
]); // 上传初始化已经完成
// 没有内部状态的上传类
class NewUpload2 {
}
// 没有内部状态的工厂函数--->单例
const uploadFactory2 = (function () {
    var flyWeightedObj = null;
    return {
        created() {
            if (flyWeightedObj) {
                return flyWeightedObj;
            }
            flyWeightedObj = new NewUpload2();
            return flyWeightedObj;
        },
    };
})();
// div对象池
const bubbleFactory = (function () {
    const bubbleList = []; // 对象池
    return {
        create() {
            // 从对象池中取一个div标签
            return (bubbleList.length === 0
                ? document.createElement("div")
                : bubbleList.shift());
        },
        recover(divDom) {
            // 回收一个div标签
            bubbleList.push(divDom);
        },
    };
})();
// 测试用例
// 第一次绘制
const tempList = []; // 临时存放的数组
function firstPaint() {
    // 需要用stringData1来进行dom的生成
    const stringData1 = ["data1", "data2", "data3", "data4"];
    for (let i = 0; i < stringData1.length; i++) {
        const div = bubbleFactory.create();
        div.innerHTML = stringData1[i];
        document.body.appendChild(div);
        tempList.push(div);
    }
}
// 重新绘制前回收
function recoverDiv() {
    document.body.innerHTML = "";
    while (tempList.length > 0) {
        bubbleFactory.recover(tempList.shift());
    }
}
// 第二次绘制
function secordPaint() {
    // 需要用stringData2来进行dom的生成
    const stringData2 = ["data5", "data6", "data7", "data8", "data9"];
    for (let i = 0; i < stringData2.length; i++) {
        const div = bubbleFactory.create();
        div.innerHTML = stringData2[i];
        document.body.appendChild(div);
        tempList.push(div);
    }
}
// 绘制过程
firstPaint();
setTimeout(recoverDiv, 4000);
setTimeout(secordPaint, 8000);
// 通用对象池的封装
function createObjectPool(createCallback) {
    const objectPool = [];
    return {
        create() {
            return (objectPool.length === 0
                ? createCallback.call(this)
                : objectPool.shift());
        },
        recover(obj) {
            objectPool.push(obj);
        },
    };
}
// 创建一个水壶工厂
function createBottle() {
    return {
        size: "",
        contentDrink: "",
    };
}
const bottlePool = createObjectPool(createBottle);
let bottle1 = bottlePool.create();
bottle1.size = "large";
bottle1.contentDrink = "orange";
bottlePool.recover(bottle1);
let bottle2 = bottlePool.create();
bottle2.size = "medium";
bottle2.contentDrink = "apple";
console.log(bottle1, bottle2, bottle1 === bottle2);
